home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / WWW / Perl_WWW_Utilities / man2html / man.cgi < prev    next >
Encoding:
Text File  |  1995-12-20  |  9.6 KB  |  325 lines

  1. #! /usr/local/bin/perl
  2. ##---------------------------------------------------------------------------##
  3. ##  File:
  4. ##      man.cgi
  5. ##  Author:
  6. ##      Earl Hood       ehood@convex.com
  7. ##  Description:
  8. ##    man.cgi is a CGI program for viewing Unix manpages.  The
  9. ##    program man2html,
  10. ##    <URL:http://www.oac.uci.edu/indiv/ehood/man2html.html>,
  11. ##    is used to convert the output from man(1) to html.
  12. ##
  13. ##    If man.cgi is invoked with no input data, it will output a
  14. ##    form for the user to select a manpage to view.
  15. ##    man.cgi can handle POST and GET methods.
  16. ##
  17. ##    The code section "Configureable Globals" is designed to
  18. ##    allow you to modify man.cgi to work with your particular
  19. ##    system configuration.
  20. ##---------------------------------------------------------------------------##
  21. ##  Copyright (C) 1995  Earl Hood, ehood@convex.com
  22. ##
  23. ##  This program is free software; you can redistribute it and/or modify
  24. ##  it under the terms of the GNU General Public License as published by
  25. ##  the Free Software Foundation; either version 2 of the License, or
  26. ##  (at your option) any later version.
  27. ##  
  28. ##  This program is distributed in the hope that it will be useful,
  29. ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31. ##  GNU General Public License for more details.
  32. ##  
  33. ##  You should have received a copy of the GNU General Public License
  34. ##  along with this program; if not, write to the Free Software
  35. ##  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  36. ##---------------------------------------------------------------------------##
  37.  
  38. ########################################################################
  39. ##    Configureable Globals
  40. ##
  41. ##    Change the value of these variables to reflect your
  42. ##    system configuration.
  43. ##
  44. ##  English name for program
  45. $ProgName    = "Manpage Viewer";
  46.  
  47. ##  man program
  48. $ManPrg        = '/usr/bin/man';
  49.  
  50. ##  man2html program
  51. $Man2html    = '/usr/local/doctools/bin/man2html';
  52.  
  53. ##  Flag if the -cgiurl option should be used
  54. $DoCgiurl    = 1;
  55.  
  56. ##  System specific arguments to man2html:
  57. ##    HP  => "-leftm 1 -topm 8"
  58. ##    Sun => "-sun"
  59. ##  See man2html documentation for more information.
  60. $ConvArgs    = "-leftm 1 -topm 8";
  61.  
  62. ##  Keyword search processing arguments for man2html.  Normally,
  63. ##  '-k' is adequate.  However, if on a Solaris system, the
  64. ##  '-solaris' option should be specified with '-k'.  See
  65. ##  man2html documentation on information about the '-solaris' option.
  66. $KeyWArgs    = "-k";            # Normal
  67. # $KeyWArgs    = "-k -solaris";    # For Solaris
  68.  
  69. ##  Possible manual sections.  This array is used to determine the
  70. ##  the choices available in an option menu.
  71. @Sections    = (
  72.     '1', '1M', '2', '3', '3C', '3F', '3X', '4', '5', '6', '7', '8', '9',
  73. );
  74.  
  75. ##  Form method.  The value is either 'GET' or 'POST'.  'GET' is
  76. ##  recommended since the URL sent by the client also contains
  77. ##  the argument information.  This allows a client's "Reload" function
  78. ##  to reprocess a currently viewed manpage.
  79. $FormMethod    = 'GET';
  80.  
  81. ##  Argument separator for CGI URL links.  As clients become more
  82. ##  SGML conformant, the simple use of '&' conflicts with
  83. ##  SGML syntax.  You can set this variable to control what is
  84. ##  used as the separator.  Possibilities:
  85. ##    &
  86. ##    &
  87. ##
  88. $ArgSep        = '&';
  89.  
  90. ##  MANPATH for man
  91. $ENV{'MANPATH'}    = "/usr/man:/usr/contrib/man:/usr/local/man";
  92.  
  93. ##    End Configureable Globals section
  94. ########################################################################
  95.  
  96. ########################################################################
  97. ##    Globals
  98. ########################################################################
  99. ($PROG = $0)    =~ s/.*\///;        # Name of program
  100. %FORM        = ();            # Array to hold form contents
  101. $Error        = '';            # Error string
  102.  
  103. ########################################################################
  104. ##    Main block
  105. {
  106.     #    Set unbuffered I/O.  Prevents buffering problems with
  107.     #    "system()" calls.
  108.     select((select(STDOUT), $| = 1)[0]);
  109.  
  110.     #    Print content-type header
  111.     &printouttype("text/html");
  112.  
  113.     #    Print man form if called w/no arguments
  114.     &printform() if &noarg();
  115.  
  116.     #    If reached here, there is input to process
  117.     &error("CGI input error") unless &parseinput();
  118.     &doit();
  119.     exit 0;
  120. }
  121. ########################################################################
  122. ##    Subroutines
  123. ########################################################################
  124. #-----------------------------------------------------------------------
  125. #    printform outputs the man selection form to the client.
  126. #
  127. sub printform {
  128.     &printhead($ProgName);
  129.     print STDOUT <<EndOfForm;
  130. <p>The following form allows you to view a manpage on this system.
  131. Please fill out the following fields and select 'Submit' to view
  132. a manpage.
  133. </p>
  134. <form method="$FormMethod" action="/cgi-bin/man.cgi">
  135. <p>Section:
  136. <select name=section>
  137. <option value="all">All Sections</option>
  138. <option value="keyword">Keyword Search</option>
  139. EndOfForm
  140.  
  141.     #    Print out possible section choices
  142.     local($section);
  143.     foreach $section (@Sections) {
  144.     print STDOUT qq|<option value="$section">Section $section</option>|;
  145.     }
  146.  
  147. print STDOUT <<EndOfForm;
  148. </select>
  149. </p>
  150. <p>Topic: <input type="TEXT" name="topic">
  151. </p>
  152. <p><input type="SUBMIT" value="Submit">
  153. </p>
  154. </form>
  155. EndOfForm
  156.     &printend();
  157.     exit 0;
  158. }
  159. #-----------------------------------------------------------------------
  160. #    doit does the conversion
  161. #
  162. sub doit {
  163.     local($section, $topic, $manexec, $htmlexec, $manout);
  164.     $manout = '';
  165.  
  166.     #    Get section and topic from input
  167.     $section = $FORM{'section'};
  168.     $topic = $FORM{'topic'};
  169.     &error("Questionable characters in topic")  if &isquestionable($topic);
  170.  
  171.     #    Determine command arguments for man and man2html
  172.     $manexec = "$ManPrg";
  173.     $htmlexec = "$Man2html";
  174.     if ($section =~ /keyword/) {
  175.     $manexec .= " -k $topic";
  176.     $htmlexec .= qq| $KeyWArgs -title "Keyword search: \\"$topic\\""|;
  177.     } else {
  178.     &error("No topic entered")  unless $topic;
  179.     $manexec .= " $section"  if $section !~ /all/;
  180.     $manexec .= " $topic";
  181.     $htmlexec .= qq| $ConvArgs -title "$topic($section)"|;
  182.     }
  183.     #    Check if doing man xref detection
  184.     if ($DoCgiurl) {
  185.     $htmlexec .= q| -cgiurl '/cgi-bin/man.cgi?| .
  186.              q|section=${section}${subsection}| .
  187.              $ArgSep .
  188.              q|topic=${title}'|;
  189.     }
  190.  
  191.     #    Execute man
  192.     if (open(MANPRG, "$manexec 2>/dev/null |")) {
  193.     $/ = 0777;
  194.     $manout = <MANPRG>;
  195.     close(MANPRG);
  196.     } else {
  197.     &error("Unable to execute '$manexec'");
  198.     }
  199.  
  200.     #    Convert output from man to html
  201.     if ($manout =~ /^\s*$/) {
  202.     &error("Nothing found for $topic");
  203.     } else {
  204.     if (open(MAN2HTML, "| $htmlexec 2>/dev/null")) {
  205.         print MAN2HTML $manout;
  206.         close(MAN2HTML);
  207.     } else {
  208.         &error("Unable to execute '$htmlexec'");
  209.     }
  210.     }
  211. }
  212. ########################################################################
  213. ##    Generic subroutines for CGI use
  214. ########################################################################
  215. #-----------------------------------------------------------------------
  216. #    noarg returns true if no arguments were passed to script.
  217. #
  218. sub noarg {
  219.     $ENV{"REQUEST_METHOD"} eq "GET" && $ENV{"QUERY_STRING"} =~ /^\s*$/;
  220. }
  221. #-----------------------------------------------------------------------
  222. #    parseinput converts the input data into the %FORM array
  223. #
  224. sub parseinput {
  225.     local($method) = ($ENV{"REQUEST_METHOD"});
  226.     local($data);
  227.     if ($method eq "GET") {
  228.     $data = $ENV{"QUERY_STRING"};
  229.     } elsif ($method eq "POST") {
  230.     read(STDIN, $data, $ENV{"CONTENT_LENGTH"});
  231.     } else {
  232.     $Error = "Unrecgonized request method : $method";
  233.     return 0;
  234.     }
  235.     local(@pairs, $name, $value);
  236.     if ($data ne '') {
  237.     @pairs = split(/&/, $data);
  238.     foreach (@pairs) {
  239.         ($name, $value) = split(/=/);
  240.         $name = &expandstr($name);
  241.         $value = &expandstr($value);
  242.         $FORM{$name} = $value;
  243.     }
  244.     }
  245.     1;
  246. }
  247. #-----------------------------------------------------------------------
  248. #    printouttype prints out specified content-type header back
  249. #    to client
  250. #
  251. sub printouttype {
  252.     local($type) = shift;
  253.     print STDOUT "Content-type: $type\r\n\r\n";
  254. }
  255.  
  256. #-----------------------------------------------------------------------
  257. #    printhead outputs html prematter
  258. #
  259. sub printhead {
  260.     local($title, $h1) = @_;
  261.     $h1 = $title  unless $h1;
  262.  
  263.     print STDOUT <<ENDOFHEAD;
  264. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
  265. <HTML>
  266. <HEAD>
  267. <TITLE>$title</TITLE>
  268. </HEAD>
  269. <BODY>
  270. <H1>$h1</H1>
  271. ENDOFHEAD
  272. }
  273.  
  274. #-----------------------------------------------------------------------
  275. #    printend outputs html postmatter
  276. #
  277. sub printend {
  278.     print STDOUT <<ENDOFEND;
  279. </BODY>
  280. </HTML>
  281. ENDOFEND
  282. }
  283.  
  284. #-----------------------------------------------------------------------
  285. #    error prints an error out to the client.
  286. #
  287. sub error {
  288.     local($str) = &htmlize(shift);
  289.     &printhead("$ProgName Error");
  290.     $str .= ":"  if $Error && $str;
  291.     $str .= " $Error";
  292.     print STDOUT "<p>$str</p>";
  293.     &printend();
  294.     exit 0;
  295. }
  296.  
  297. #-----------------------------------------------------------------------
  298. #    htmlize translates special characters to enitity refs.
  299. #
  300. sub htmlize {
  301.     local($str) = shift;
  302.     $str =~ s/&/\&/g;
  303.     $str =~ s/</\</g;
  304.     $str =~ s/>/\>/g;
  305.     $str;
  306. }
  307. #-----------------------------------------------------------------------
  308. #    expandstr translates hex codes to characters
  309. #
  310. sub expandstr {
  311.     local($str) = shift;
  312.     $str =~ tr/+/ /;
  313.     $str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ge;
  314.     $str;
  315. }
  316. #-----------------------------------------------------------------------
  317. #    isquestionable determines if $str contains questionable
  318. #    characters if $str is used in a subshell invocation.
  319. #
  320. sub isquestionable {
  321.     local($str) = shift;
  322.     $str !~ /^[a-zA-Z0-9_\-+ \t\/@%]+$/;
  323. }
  324. ########################################################################
  325.